package www.wmx.com.xssc.util.similarity;

import com.hankcs.hanlp.seg.common.Term;

import java.util.*;

public class BM25Similarity {

    // 假设的k1和b参数，这些通常需要根据实际情况进行调整
    private static final double K1 = 1.5;
    private static final double B = 0.75;

    public  static  double getBM25Similarity(String s1,String s2){
        List<Term> termList1 = HanLPPreprocessor.segment(s1);
        List<Term> termList2 = HanLPPreprocessor.segment(s2);
        double similarity = calculateSimilarity(termList1, termList2);
        return  similarity;
    }

    // 计算两个文本片段之间的BM25相似度得分
    private static double calculateSimilarity(List<Term> text1, List<Term> text2) {
        // 创建两个文本的词频映射
        Map<String, Integer> freqMap1 = new HashMap<>();
        Map<String, Integer> freqMap2 = new HashMap<>();

        for (Term term : text1) {
            freqMap1.put(term.word, freqMap1.getOrDefault(term.word, 0) + 1);
        }

        for (Term term : text2) {
            freqMap2.put(term.word, freqMap2.getOrDefault(term.word, 0) + 1);
        }

        double score = 0.0;
        int text1Length = text1.size();
        int text2Length = text2.size();

        // 遍历第一个文本的词，计算其在第二个文本中的BM25得分
        for (Map.Entry<String, Integer> entry : freqMap1.entrySet()) {
            String word = entry.getKey();
            int freq1 = entry.getValue();
            int freq2 = freqMap2.getOrDefault(word, 0);

            // 计算idf部分（这里我们假设文档集合的大小足够大，因此idf为常数）
            double idf = Math.log(2.0); // 简化的idf计算，实际应基于整个文档集合

            // 计算tf部分
            double tf2 = (freq2 * (K1 + 1)) / (freq2 + K1 * (1 - B + B * text2Length));

            // 累加得分
            score += idf * tf2 * freq1;
        }

        // 归一化
        score *= (K1 + 1) / (text1Length + K1 * (1 - B + B * text1Length));

        // 由于我们计算的是两个文本片段之间的相似度，最终得分可能需要进一步调整或归一化
        // 这里的实现是基于简化的假设，可能不适用于所有情况

        return score;
    }

}